package cn.edu.ctbu.dp01.api;

import cn.edu.ctbu.dp01.constant.REnum;
import cn.edu.ctbu.dp01.entity.student;
import cn.edu.ctbu.dp01.exception.RException;
import cn.edu.ctbu.dp01.service.StudentService;
import cn.edu.ctbu.dp01.util.Rutil;
import cn.edu.ctbu.dp01.vo.QueryObj;
import cn.edu.ctbu.dp01.vo.R;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/api/student")
public class StudentApiController {

    @Autowired
    private final StudentService studentService;

    public StudentApiController(StudentService studentService) {
        this.studentService = studentService;
    }

    @GetMapping("/list")
    public R<List<student>> findall() {
        List<student> students = studentService.getAll();
        return Rutil.success(students);
    }

    @GetMapping("/id/{id}")
    public R<student> findById(@PathVariable int id) {
        student students = studentService.getById(id);
        return Rutil.success(students);
    }

    @PostMapping("/add")
    public R<student> add(@RequestBody student student) {
        if (student == null) {
            throw new RException(REnum.PARAM_ERR);
        }
        student addedStudent = studentService.add(student);
        return Rutil.success(addedStudent);
    }

    @PutMapping("/update")
    public R<student> update(@RequestBody student student) {
        System.out.println("接收到的更新数据：" + student); // 打印日志
        if (student == null) {
            throw new RException(REnum.PARAM_ERR);
        }
        student updatedStudent = studentService.update(student);
        return Rutil.success(updatedStudent);
    }

    @DeleteMapping("/delete/{id}")
    public R<Void> delete(@PathVariable Integer id) {
        studentService.delete(id);
        return Rutil.success();
    }

    @GetMapping("/validataUser")
    public R validateSnoAndPassword( String sno,String password) throws Exception{

        return Rutil.success(studentService.validateUsernameAndPassword(sno, password));

    }

    @PostMapping("/getbypage")
    public R<List<student>> getByPage(@RequestBody QueryObj<?> qObj) {
        String sortField = qObj.getSortField() != null ? qObj.getSortField() : "id";
        String sortOrder = qObj.getSortOrder() != null && qObj.getSortOrder().equalsIgnoreCase("asc") ? "ASC" : "DESC";
        Sort sort = Sort.by(Sort.Direction.fromString(sortOrder), sortField);

        int pageIndex = qObj.getPageIndex() != null ? qObj.getPageIndex() - 1 : 0;
        int pageSize = qObj.getPageSize() != null ? qObj.getPageSize() : 10;
        Pageable pageable = PageRequest.of(pageIndex, pageSize, sort);

        Object data = qObj.getData();
        if (data == null) {
            Page<student> students = studentService.getAll(pageable);
            return Rutil.success(students.getContent(), students.getTotalElements());
        }

        try {
            ObjectMapper mapper = new ObjectMapper();
            student studentData = mapper.convertValue(data, student.class);

            ExampleMatcher matcher = ExampleMatcher.matching()
                    .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains())
                    .withMatcher("age", ExampleMatcher.GenericPropertyMatchers.exact())
                    .withIgnoreNullValues();

            Example<student> example = Example.of(studentData, matcher);
            Page<student> studentPage = studentService.getAll(example, pageable);
            return Rutil.success(studentPage.getContent(), studentPage.getTotalElements());
        } catch (Exception e) {
            throw new RException(REnum.QUERY_ERR);
        }
    }
    @PostMapping("/deletebatch")
    public R<Void> deleteBatch(@RequestBody List<Integer> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new RException(REnum.PARAM_ERR);
        }
        studentService.deleteBatch(ids);
        return Rutil.success();
    }

}
